#coding=utf-8
import subprocess
import platform
import os
import time
import re

PATH=lambda p:os.path.abspath(p)

system=platform.system()
if system is 'Windows':
    find_util='findstr'
else:
    find_util='grep'

if 'ANDROID_HOME' in os.environ:
    # command=os.path.join(
    #     os.environ['ANDROID_HOME'],
    #     'platform-tools',
    #     'adb'
    # )
    command="adb "
else:
    raise EnvironmentError("Adb not found in $ANDROID_HOME path: %s." %
        os.environ["ANDROID_HOME"])


class ADB:
    def __init__(self,device_id=''):
        '''
        :param device_id: 设备序号
        '''
        self.device_id=device_id

    def adb(self,args):
        '''
        subprocess.run()	Python 3.5中新增的函数。执行指定的命令，等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。
        subprocess.call()	执行指定的命令，返回命令执行状态，其功能类似于os.system(cmd)。
        :param args:
        :return:
        '''
        cmd = '%s %s ' % (command, str(args))
        return subprocess.Popen(
            cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE
        )


    def shell(self, args):
        if self.device_id=='':
            cmd = "%s shell %s " % (command,str(args))
            pass
        else:
            cmd="%s -s %s shell %s" % (command,self.device_id,str(args))
        return subprocess.Popen(
            cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )

    def shell_multiple(self,args):
        if self.device_id=='':
            cmd = '%s shell ' % (command)
            pass
        else:
            cmd='%s -s %s shell ' % (command,self.device_id)
        p= subprocess.Popen(cmd, shell=True,stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        commands="\n".join(args.split('&'))+"\nexit\n"
        if "su" in args:
            commands=commands+"\nexit\n"+"\nexit\n"
        return p.communicate(commands)[0]  #(stdout, stderr)

        pass

    def get_android_version(self):
        version= self.shell('getprop ro.build.version.release').stdout.read().strip().decode()
        return version

    def get_sdk_version(self):
        """
        获取设备SDK版本号
        """
        return self.shell("getprop ro.build.version.sdk").stdout.read().strip().decode()

    def logcat_c(self):
        return self.adb('logcat -c')

    def logcat(self, log_path):
        return self.adb('logcat -v time *:W > %s&' % (log_path))

    def get_cpu_version(self):
        """
               获取cpu基带版本
               :return: arm64-v8a
               """
        t = self.shell("getprop ro.product.cpu.abi ").stdout.readlines()
        if t:
            return(t[0].decode().strip())
        return t

    def rm_minicap_jpg(self, remote_file):
        '''
        删除minicap缓存图片
        :param filename:
        :return:
        '''
        self.shell('rm -r /data/local/tmp/%s.jpg' % (remote_file))

    def rm(self, param):
        return self.shell(param)

    def screen_shot(self, computer_path):
        self.shell('/system/bin/screencap -p /sdcard/temp.png')
        time.sleep(5)
        self.adb('pull /sdcard/temp.png %s' % computer_path)

    def pull(self, remote_path, computer_path):
        return self.adb('pull %s %s ' % (remote_path,computer_path))

    def get_cpu(self, package_name):
        '''
        获取当前cpu百分百
        :param package_name:
        :return:
        '''
        p=self.shell('top -d 1 -n 1 ')
        # p = self.shell('cat /proc/cpuinfo | %s %s '% (find_util, package_name) )
        start_time=int(time.time())
        while int(time.time())-start_time<30:
            line=p.stdout.readline()
            if line:
                r = line.strip().decode('utf-8')
                if r.endswith(package_name):
                    lst = [cpu for cpu in r.split(' ') if cpu]
                    p.communicate()
                    return int(lst[2].split('%', 1)[0])
        return 0

    def __mem_pss(self, package_name):
        """
        获取当前应用内存
        """
        p = self.shell(
            'top -n 1 -d 1 | %s %s' %
            (find_util, package_name))
        while True:
            r = p.stdout.readline().strip().decode('utf-8')
            if r.endswith(package_name):
                lst = [mem for mem in r.split(' ') if mem]
                return int(lst[6].split('K')[0])

    def __mem_pss_by_dumpsys(self,package_name):
        p = self.shell(
            'dumpsys meminfo %s | %s TOTAL' %
            (package_name,find_util))
        while True:
            r = p.stdout.readline().strip().decode('utf-8')
            if r and 'TOTAL' in r:
                lst = [MemTotal for MemTotal in r.split(' ') if MemTotal]
                p.communicate()
                return int(lst[1])
            if not r:
                return 0

    def __mem_mem_total(self):
        p = self.shell('cat proc/meminfo')
        while True:
            r = p.stdout.readline().strip().decode('utf-8')
            if r and 'MemTotal' in r:
                lst = [MemTotal for MemTotal in r.split(' ') if MemTotal]
                p.communicate()
                return int(lst[1])
            if not r:
                return -1

    def get_mem_avaliable(self):
        p = self.shell('free')
        while True:
            r = p.stdout.readline().strip().decode('utf-8')
            if r and 'Mem' in r:
                lst = [MemTotal for MemTotal in r.split(' ') if MemTotal]
                p.communicate()
                return int(lst[3])/1024
            if not r:
                return 0

        pass

    def get_mem(self, package_name):
        """
        获取当前内存百分比
        """
        cur_mem=self.__mem_pss_by_dumpsys(package_name)
        total= float(self.__mem_mem_total())
        try:
            return cur_mem,int((cur_mem/total)*100)
        except:
            return None

    def get_app_version_name(self, package_name):
        """
        获取指定应用的versionName
        :param package:应用包名
        :return: 包名,versionName
        """
        for package in self.shell('dumpsys package %s' % package_name).stdout.readlines():
            if 'versionName' in package.decode():
                return package.decode().split('=',2)[1].strip()

    def get_device_name(self):
        """
        :return: 设备名 :TCLxxx
        """
        t = self.shell("getprop ro.product.model").stdout.readline()
        return ''.join(t.decode()).strip()

    # 获取到元素到坐标点击，主要解决浮动层遮档无法触发driver.click的问题
    def tap(self, x, y):
        self.shell(" input tap "+ str(x) + " " + str(y))

    def get_disk(self):
        """
        获取手机磁盘信息
        :return: Used:用户占用,Free:剩余空间
        """
        for s in self.shell('df').stdout.readlines():
            if '/mnt/shell/emulated' in s.decode() or '/storage/sdcard0' in s.decode():
                lst = []
                for i in s.decode().split(' '):
                    if i:
                        lst.append(i)
                return 'Used:%s,Free:%s' % (lst[2], lst[3])

    def wifi_name(self):
        """
        查询连接wifi名称
        """
        for package in self.shell('dumpsys wifi').stdout.readlines():
            if package.decode().startswith('mWifiInfo'):
                wifi_name = re.findall(r'SSID:([^"]+), BSSID', package.decode())
                if not wifi_name:
                    return 'Wired' #有线
                else:
                    return wifi_name[0].strip()

    def get_screen_resolution(self):
        """
        获取设备屏幕分辨率，return (width, high)
        """
        pattern = re.compile(r"\d+ x \d+")
        out = self.shell("dumpsys display | %s DisplayDeviceInfo" %
            find_util).stdout.read()
        #python2 必须decode设置为utf-8
        display = pattern.findall(out.decode("utf-8"))
        tmp=display[0].split('x')

        return int(tmp[0].strip()), int(tmp[1].strip())


    def get_front_package_name(self):
        '''
        获取前端包名
        :return:
        '''
        try:
            pattern = re.compile(r"u0 ([a-zA-Z0-9.]+)")
            out = self.shell(" dumpsys window | %s mCurrentFocus" % find_util).stdout.read()
            result = pattern.search(out.decode())
            return result.group(1)
        except:
            return None

    def get_current_activity(self):
        '''
        获取前端应用acitivity 名称
        :return:
        '''
        try:
            pattern = re.compile(r"u0 ([a-zA-Z0-9./]+)")
            out = self.shell(" dumpsys activity | %s Focuse" % find_util).stdout.read()
            result = pattern.search(out.decode())
            return result.group(1).split("/")[1]
        except:
            return None

    def stop_play(self,num):
        for i in range(num):
            commandsss='adb shell "sendevent /dev/input/event0 1 158 1 && sendevent /dev/input/event0 0  0  0 && sendevent /dev/input/event0 1 158 0 && sendevent /dev/input/event0 0  0  0" '
            os.system(commandsss)
            command2 = 'adb shell "sendevent /dev/input/event0 1 15 1 && sendevent /dev/input/event0 0  0  0 && sendevent /dev/input/event0 1 15 0 && sendevent /dev/input/event0 0  0  0" '
            os.system(command2)  # 机器适配
            # time.sleep(1)

    def keyevent(self,keycode):
        self.shell(' input keyevent %s ' % keycode).stdout.read()#异步阻塞
        pass

    def keyevent_natvie(self,keycode,ir_device='/dev/input/event0'):
        '''
        直接将事件注入到底层
        :param keycode:
        :return:
        '''
        #self.shell(' input keyevent %s ' % keycode).stdout.read()#异步阻塞
        # if self.device_id=='':
        #     cmd = '%s shell ' % (command)
        #     pass
        # else:
        #     cmd='%s -s %s shell ' % (command,self.device_id)
        commands='\nsendevent {ir_device} 1 {code} 1 & sendevent {ir_device} 0  0  0 & sendevent {ir_device} 1 {code} 0 & sendevent {ir_device} 0  0  0 '  .format(ir_device=ir_device, code=keycode)
        # print( commands)
        # p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        # commands = commands.split('&')
        # for line in commands:
        #     p.stdin.write(line)
        #     p.stdin.flush()
        # p.stdin.writelines(commands)
        # p.stdin.flush()
        self.shell_multiple(commands)
        pass

    def swipe(self,x1,y1,x2,y2,during):
        self.shell(' input swipe %s %s %s %s %s ' % (x1,y1,x2,y2,during)).stdout.read()


if __name__ == '__main__':
    adb =ADB()
    # while True:
    # print(adb.get_device_name())
    # print(adb.get_package_name())

    # pattern = re.compile(r"\d+ x /")
    # out=os.popen(
    #     'adb -s 192.168.1.101:5555 shell "dumpsys activity | grep mCurrentFocus" ')
    # print(out.read())
    # pattern = re.compile(r"u0 ([a-zA-Z0-9.]+)")
    # out = subprocess.Popen(
    #     'adb -s 192.168.1.101:5555 shell dumpsys window | findstr mCurrentFocus', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    # ).stdout.read()
    # t= pattern.search(out.decode())
    # print(out)
    # print(t.group(1))
    # for line in out.readlines():
    #     print(line)
    # print(out.readlines())

    # adb.shell(commandsss)
    # adb.get_front_package_name()adb shell
    # adb.get_screen_resolution()
    # adb.swipe(100,20,2000,20,900)
    # while True:
    #     print adb.get_mem("com.tcl.cyberui")
    # print adb.shell_multiple("ls&am force-stop com.tcl.cyberui & am start com.tcl.cyberui/.MainActivity")
    begin=time.time()
    # for i in range(12):
    #     start_time=time.time()
    #     print "start_time="+str(start_time)
    #     adb.keyevent(22)
    #     end_time = time.time()
    #     print "end_time=" + str(start_time)
    #     print "cost="+str(end_time-start_time)

    # p = subprocess.Popen("adb shell", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    # command = "tclsu\n"
    # for i in range(13):
    #     # command = command + str(3) + "\n"
    #     print i
    #     print p.communicate(str(3) + "\n")
    #     pass
    # print("===========")
    # print(command)
    # commands = command + "cd data/local/tmp\nls\nexit\n"
    # print p.communicate( commands)[0]
    # s = 'am start -a com.tcl.vod.action.videosort --es channe_id movie --es channe_name MOIVE'
    # print adb.shell_multiple(s)

    # adb.keyevent_natvie(102)
    adb.get_cpu("com.tcl.cyberui")
    stop = time.time()
    print "total=" + str(stop - begin)
